package sspersonserver.protocol;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import sspersonserver.Client;
import sspersonserver.LoginData;
import sspersonserver.Server;
import sspersonserver.subjects.*;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by IntelliJ IDEA.
 * User: Double
 * Date: 15.01.12
 * Time: 20:58
 * To change this template use File | Settings | File Templates.
 */
public class Protocol
{
	/*From Client to Server*/
	public static final String auth = "Auth";
	public static final String getList = "GetList";
	public static final String getNext = "GetNext";
	public static final String update = "Update";
	public static final String create = "Create";
	public static final String getPerson = "GetPerson";
	public static final String getCountry = "GetCountry";
	public static final String getCity = "GetCity";
	public static final String getStreet = "GetStreet";
	public static final String getPhoneType = "GetPhoneType";
	public static final String setCountry = "SetCountry";
	public static final String setCity = "SetCity";
	public static final String setStreet = "SetStreet";
	public static final String setPhoneType = "SetPhoneType";
	public static final String removePerson = "RemovePerson";

	/*From Server to Client*/
	public static final String person = "Person"; // Contains serialized FullPerson data
	public static final String country = "Country"; // Serialized list of Countries
	public static final String city = "City"; // Serialized list of Cities
	public static final String street = "Street"; // Serialized list of Cities
	public static final String phoneType = "PhoneType"; // Serialized list of Phones
	public static final String newList = "NewList"; // First n elements
	public static final String nextList = "NextList"; // Next n elements from current position
	/*
`Login status:     -1 - fail
						0- admin
						1-superuser
						2-user
	*/
	public static final String loginStatus = "LoginStatus";

	public static final String modStatus = "ModStatus";
	public static final String modSuccess = "Success";
	public static final String modFail = "Fail";

	/*Types of user auth*/
	public static final int failAuth = -1;
	public static final int adminAuth = 0;
	public static final int superUserAuth = 1;
	public static final int userAuth = 2;


	/*PersonList*/
	private ArrayList<Person> persons;




	public boolean decodeSystemPacket(String inputString, Client client)
	{
		boolean ret = true;
		Gson gson = new Gson();
		System.out.println("to decode: "+inputString);
		Packet p = null;
		if (inputString != null)
		{
			p = gson.fromJson(inputString, Packet.class);
			System.out.println("Type:"+p.getType()+" Data:"+p.getData());

			if (p.getType().equalsIgnoreCase(Protocol.auth))
			{

				LoginData loginData = gson.fromJson(p.getData(),LoginData.class);
				int authState = Server.getDbHandler().checkAuth(loginData);
				if(authState!=-1)
				{
					client.setAuthState(authState);
					client.sendMsg(encode(Protocol.loginStatus, String.valueOf(authState)));
				}
				else
				{
					Server.getClientProcessor().removeClient(client);
					client.sendMsg(encode(Protocol.loginStatus, String.valueOf(Protocol.failAuth)));
					client.disconnect();
				}


			}
			else if (p.getType().equalsIgnoreCase(Protocol.getList))
			{
				System.out.println("Protocol GetList invoked");
				client.setCurPos(0);
				client.setAmountPerPage(Integer.parseInt(p.getData()));
				persons = Server.getDbHandler().getPersonList(client.getCurPos(),client.getAmountPerPage());
				client.sendMsg(encode(Protocol.newList,gson.toJson(persons)));
				client.setCurPos(client.getCurPos()+persons.size());

			}
			else if (p.getType().equalsIgnoreCase(Protocol.getNext))
			{
				persons = Server.getDbHandler().getPersonList(client.getCurPos(),client.getCurPos()+client.getAmountPerPage());
				if(persons.size()>0)
				{
				client.sendMsg(encode(Protocol.nextList,gson.toJson(persons)));
				client.setCurPos(client.getCurPos()+client.getAmountPerPage());
				}

			}
			else if (p.getType().equalsIgnoreCase(Protocol.update))
			{
				FullPerson fullPerson = gson.fromJson(p.getData(),FullPerson.class);
				if(fullPerson.getPerson().getID()>0)
				{
					Server.getDbHandler().update(fullPerson);
				}
				else
				{
					Server.getDbHandler().saveFullPerson(fullPerson);
				}
			}
			else if (p.getType().equalsIgnoreCase(Protocol.getPerson))
			{
				client.sendMsg(encode(Protocol.person, gson.toJson(Server.getDbHandler().getFullPerson(Integer.parseInt(p.getData())))));
				                                                                                         
			}
			else if (p.getType().equalsIgnoreCase(Protocol.getCountry))
			{
				client.sendMsg(encode(Protocol.country, gson.toJson(Server.getDbHandler().getCountry())));
			}
			else if (p.getType().equalsIgnoreCase(Protocol.getCity))
			{
				client.sendMsg(encode(Protocol.city, gson.toJson(Server.getDbHandler().getCity(Integer.parseInt(p.getData())))));
			}
			else if (p.getType().equalsIgnoreCase(Protocol.getStreet))
			{
				client.sendMsg(encode(Protocol.street, gson.toJson(Server.getDbHandler().getStreet(Integer.parseInt(p.getData())))));
			}
			else if (p.getType().equalsIgnoreCase(Protocol.getPhoneType))
			{
				client.sendMsg(encode(Protocol.phoneType, gson.toJson(Server.getDbHandler().getPhoneType())));
			}
			else if (p.getType().equalsIgnoreCase(Protocol.setCountry))
			{
				Server.getDbHandler().addCountry(gson.fromJson(p.getData(), Country.class));	
			}
			else if (p.getType().equalsIgnoreCase(Protocol.setCity))
			{
				Server.getDbHandler().addCity(gson.fromJson(p.getData(), City.class));	
			}
			else if (p.getType().equalsIgnoreCase(Protocol.setStreet))
			{
				Server.getDbHandler().addStreet(gson.fromJson(p.getData(), Street.class));
			}
			else if (p.getType().equalsIgnoreCase(Protocol.setPhoneType))
			{
				Server.getDbHandler().addPhoneType(gson.fromJson(p.getData(),PhoneType.class));
			}
			else
			{
				ret = false;
			}
		}
			return ret;
		}

	public String encode(String type, String data)
	{
		String ret;
		Packet p= new Packet(type,data);
		Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).serializeNulls().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
		ret = gson.toJson(p);
		System.out.println("encoded: "+ret);
		return ret+"\n";
	}

}
